 
<#------------------------------------------------------------------------------------------------------------------
	private 以下三个宏仅限于在本文件中自用，外部不建议使用。
-------------------------------------------------------------------------------------------------------------------->
<#-- 组件label的通用宏定义。  -->
<#-- @param label 		组件label的文本。-- >
<#-- @param label 		组件label的文本。-- >
<#-- @param labelWidth 	组件label的宽度，单位为像素。-- >
<#-- @param required	是否为必填组件，必填组件的label上需标红色星号，默认为false。-->
<#macro labelable label labelWidth required=false>
	<#-- 默认可以通过在ftl中使用<#global defaultLabelWidth=xxx>的方式对ftl中的全部labelable组件设置label宽度。 -->
	<#if labelWidth==null && defaultLabelWidth!=null>
		<#assign labelWidth=defaultLabelWidth>
	<#-- 如果没有全局默认宽度，也没有自定义宽度，则需要给出一个默认值。 -->
	<#elseif labelWidth=null>
		<#assign labelWidth=100>
	</#if>
	<#-- 绘制label -->
	<label class="widget-label  ${required?string('required', '')}" <#if labelWidth??>style="width:${labelWidth}px !important;"</#if>><#if label??>${label}<span class="colon"></span></#if></label>
</#macro>

<#-- 组件的标准布局。 -->
<#-- @param id 							组件ID。 -->
<#-- @param widgetType 					组件类型。 -->
<#-- @param columnScale 				网格布局下的列比例，如果将组件放置在响应式网格布局中，需要在此指定在列布局中占用几分之一。 -->
<#-- 									以bootstrap经典的12列模式为例，如果此属性设置为2，则此组件会被设置col-md-6样式，即总列数除以此属性的数值。  -->
<#-- 									使用这种设计主要用于开发方便，不需要每次再计算列宽，当总列数改变的时候也不会受到影响。 -->
<#-- 									默认为2。 -->
<#-- @param propertyPath 				过滤项对应的（实体模型）属性路径。 -->
<#-- @param filterType					过滤项的类型。可选项：IN, NOTIN, RANGE, CUSTOM。可为空，为空则会在后台设置为SINGLE。 -->
<#-- @param operator					过滤项的操作符。应用到where语句中时字段和值之间的操作符。 -->
<#-- @param label labelWidth required 	请参考<#macro labelable>。 -->
<#-- @param showLabel 是否显示label属性 默认显示-->
<#macro widget widgetType id label labelWidth required columnScale propertyPath filterType operator style class showLabel=true labelPos="left">
	<#-- 默认可以通过在ftl中使用<#global defaultColumnScale=xxx>的方式对ftl中的全部组件设置宽度比例。 -->
	<#if columnScale==null && defaultColumnScale!=null>
		<#assign columnScale=defaultColumnScale>
	<#-- 如果没有全局默认比例，也没有自定义比例，则需要给出一个默认值。 -->
	<#elseif columnScale=null>
		<#assign columnScale=1>
	</#if>
	
	<#-- widgetType会应用到class中，供前台jQuery选取。默认总列数为24。 -->
	<div <#if id??>id=${id}</#if> <#if style??>style="${style}"</#if> data-magic-widget-type="${widgetType}" class="<#if labelPos="top">magic-widget-topbottom<#else>magic-widget</#if> magic-${widgetType} col-md-${24/columnScale} <#if class??>${class}</#if>" <#if propertyPath??>data-property-path="${propertyPath}"</#if> <#if filterType??>data-filter-type="${filterType}"</#if> <#if operator??>data-operator="${operator}"</#if>>
		<#if showLabel>
			<@labelable label=label labelWidth=labelWidth required=required />
		</#if>
		<div class="widget-body">
			<#nested>
		</div>
	</div>
</#macro>

<#-- 组件通用属性设置。 -->
<#-- @param name 			组件的名称，用于表单的提交。 -->
<#-- @param value 			组件的值，用于显示已有的值。 -->
<#-- @param placeholder		HTML5 placeholder属性，用于在字段为空时显示一些提示信息。 -->
<#-- @param disabled		是否禁用组件。布尔类型，可选值为true或false。 -->
<#-- @param readonly		是否只读。布尔类型，可选值为true或false。 -->
<#macro attributes name value placeholder disabled=false readonly=false>
	<#-- 属性设置的逻辑很简单。属性存在则设置相关属性，否则不设置。 -->
	<#if name??>name="${name}"</#if> <#if value??>value="${value}"</#if> <#if placeholder??>placeholder="${placeholder}"</#if> <#if disabled>disabled="disabled"</#if> <#if readonly>readonly="readonly"</#if>  
</#macro>




<#------------------------------------------------------------------------------------------------------------------
	public 	以下供外部使用。
-------------------------------------------------------------------------------------------------------------------->
<#-- 文本输入框、密码框 -->
<#macro text 
	label labelWidth required 
	style class labelPos
	id name value placeholder propertyPath filterType operator disabled readonly prefix suffix
	inputType="text" columnScale=3>
	<div class="layui-inline layui-col-xs${12/columnScale}">
		<label class="layui-form-label">${label}</label>
		<div class="layui-input-block">
			<input type="${inputType}" filterType="${filterType}" class="layui-input search-item" <@attributes name=name value=value?html placeholder=placeholder disabled=disabled readonly=readonly /> />
		</div>
	</div>
</#macro>

<#macro select2 
	label labelWidth required 
	style class labelPos
	id name value placeholder propertyPath filterType operator disabled readonly prefix suffix
	columnScale=3>
	<div class="layui-inline layui-col-xs${12/columnScale}">
		<label class="layui-form-label">${label}</label>
		<div class="layui-input-block">
			<select name="${name}" class="search-item" type="select" filterType="${filterType}">
				<#nested>
			</select>
		</div>
	</div>
</#macro>

<#-- 国际化文本输入框 -->
<#macro i18ntext label labelWidth required 
	columnScale style class
	name value0 value1 value2 value3 value4 value5 placeholder propertyPath filterType operator disabled readonly labelPos id="i18ntext_${model.clientId}"
	inputType="text">
	<@widget widgetType="text" id=id label=label labelWidth=labelWidth required=required columnScale=columnScale style=style class=class  labelPos=labelPos propertyPath=propertyPath filterType=filterType operator=operator >
		<#local value=[value0,value1,value2,value3,value4,value5] /> 
		<input type="${inputType}" class="form-control" <#if (model.supportedLocales?size==1)>name="${name}"</#if><@attributes value="${value[model.localeIndex]}" placeholder=placeholder disabled=disabled readonly=readonly /> />
		
		<#if (model.supportedLocales?size>1)>
		<ul aria-labelledby="dropdownMenu1" class="dropdown-menu" role="menu">
	 	<#list model.supportedLocales as locale>
	    <li class="i18ntext-input-list">
	    	<span class="i18ntext-language-name">${locale.text}</span>
	    	<div class="i18ntext-input-wrap">
	    		<input type="text" name="${name}" class="form-control" value="${value[locale.index]}"/>
	    	</div>
	    </li>
	    </#list>
	  	</ul>
	  	<script>
	  		var input0=$('#${id}').find('input')[0],
	  		ul=$('#${id}').find('ul'),
	  		input=ul.find('input'),
	  		length=input.length,
	  		next;
	  		input0.onfocus=function(e){
	  			ul.css({
					padding:5,
					left: $(this)[0]['offsetLeft'],
					top: $(this)[0]['offsetHeight'],
					width: $(this)[0]['offsetWidth']
				}).show();
				
	  			input[0].focus();
			}
	  		ul.on('keydown','input',function(e){
	  			 if(e.keyCode==13){
	  				$(this).parents('li').next().find('input').focus();
				 }
	  		});
			 $(document).on('mousedown', function(e){
				 if ($(e.target).closest('.dropdown-menu').length === 0) {
					 closeI18ntext();
			        }
			 });
			 
			 input[length-1].onkeydown=function(e){
				 if(e.keyCode==9||e.keyCode==13){
					 closeI18ntext();
				 }
			 }
			 function closeI18ntext(){
				 input0.value=(input[${model.localeIndex}].value);
				 ul.hide();
			 }
	  	</script>
	  	</#if>
	</@widget>
</#macro>

<#-- 大文本输入框 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro textarea 
	label labelWidth required 
	columnScale style class labelPos
	id name value placeholder propertyPath filterType operator disabled readonly rows="5" >
	<div class="layui-form-item layui-form-text">
	    <label class="layui-form-label">${label}</label>
	    <div class="layui-input-block">
			<textarea class="layui-textarea layui-input" rows="${rows}" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly />>${value}</textarea>
		</div>
	</div>
</#macro>

<#-- 富文本编辑器 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro richeditor
	label labelWidth required 
	columnScale style class labelPos
	id name value placeholder propertyPath filterType operator disabled readonly autoHeightEnabled=false height=200>
	<@widget widgetType="richeditor" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale style=style class=class >
		<textarea id="_txt_${name}_${model.clientId}" rows="5" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly />>${value}</textarea> 
		<script>
			require(['ueditorconfig','ueditor'], function(){
				UE.getEditor('_txt_${name}_${model.clientId}', {
					initialFrameHeight: ${height},
					zIndex : 10000,
					autoHeightEnabled : ${autoHeightEnabled?string("true","false")},
					wordCountMsg : '当前已输入{#count}个字符',
					maximumWords : 100000000
				})
			});
		</script>
	</@widget>
</#macro>

<#-- 下拉框 -->
<#-- @param entitySymbol 		实体符号。主要影响数据加载时使用的数据表。 -->
<#-- @param labelProperty 		显示属性。即下拉选项中看到的文本取自该实体哪个字段，默认取实体模型中的显示文本，如为空默认取name。 -->
<#-- @param valueProperty 		值属性。即下拉返回的值是该实体中哪个字段。 -->
<#-- @param includeEmpty 		是否包含空。选项的第一个选项是否是空选项 -->
<#-- @param whereClause 		where子句。查询时的where片段，不需要带where关键字。 -->
<#-- @param orderClause 		order子句。查询时的order片段，不需要带order关键字。 -->
<#-- @param remoteQueryClass 	远程查询类。自定义的查询类，即上述参数无法支持查询操作时，允许创建一个查询类用于查询。该类在进入页面时根据值查询和输入文本过滤时都会被调用。需要实现magicsoft.jersey.service.SelectItemQuery接口。 -->
<#-- @param extraQueryParams 	额外的查询参数。除了上述查询参数外的参数，一般需要自己去处理。 -->
<#-- @param options 			下拉框的数据源。类型为freemarker能够识别的集合类型。 -->
<#-- @param queryMode			查询类型。可选项为client和remote。 -->
<#-- @param quickCreateUrl		下拉选择数据源没有时，提供快捷创建url。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro select 
	label labelWidth required 
	columnScale style class labelPos
	id name value placeholder propertyPath filterType operator quickCreateUrl quickCreateStyle quickCreateTitle
	entitySymbol labelProperty valueProperty whereClause enumType orderClause remoteQueryClass extraQueryParams options prefix suffix tags=false textOnly=false readonly=false disabled=readonly multiple=false includeEmpty=!multiple queryMode="client" >
	<@widget widgetType="select" id=id label=label labelWidth=labelWidth required=required columnScale=columnScale labelPos=labelPos style=style class=class propertyPath=propertyPath filterType=filterType operator=operator >
		<#local selectId="_lst_${model.randomHex}_${model.clientId}"/>
		<div class="input-group form_select" style="width:100%;">
			${prefix}
			<select class="form-control" style="width:100%;" id="${selectId}" <#if multiple>multiple="multiple"</#if> <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly />>
			<#assign unSelected=true />
			<#if queryMode=="client">
				<#if !(options??)><#local options=getSelectItems(entitySymbol,includeEmpty,whereClause,orderClause,valueProperty,labelProperty,remoteQueryClass,value,extraQueryParams,queryMode,enumType) /></#if>
				<#list options as option>
					<option value="${option.id}" 
						<#if multiple>${value!?seq_contains(option.id)?string("selected","")}
							<#if value!?seq_contains(option.id)><#assign unSelected=false /></#if>
						<#else>${(value==option.id)?string("selected","")}
							<#if value==option.id><#assign unSelected=false /></#if>
						</#if>>${option.text}
					</option>
				</#list>
				<#if tags && unSelected && value??>
					<option value="${value}" selected>${value}</option>
				</#if>
			<#else>
				<#assign selectItems=getSelectItems(entitySymbol,includeEmpty,whereClause,orderClause,valueProperty,labelProperty,remoteQueryClass,value,extraQueryParams,queryMode,enumType)/>
				<#list selectItems as option>
					<option value="${option.id}" selected>${option.text}</option>
				</#list>
				<#if tags && selectItems??>
					<option value="${value}" selected>${value}</option>
				</#if>
			</#if>
			</select>
			${suffix}
			<#if quickCreateUrl?? && quickCreateUrl!="">
				<span class='input-group-addon quick-create' style='cursor: pointer;'><i class="fa fa-pencil-square-o" aria-hidden="true"></i></span>
			</#if>
		</div>
		<div class="readonly-hidden">
		<#if readonly>
			<#if value?is_sequence>
				<#list value as v><input type="hidden" name="${name}" value="${v}" /></#list>
			<#else>
				<input type="hidden" name="${name}" value="${value}" />
			</#if>
		</#if>
		<#--如果是多选下拉框时-->
		</div>
		
		<div class="multiple-hidden">
		<#if textOnly && multiple  >
				<input type="hidden" name="${name}" value="${value}" />
		<#elseif multiple>
			<input type="hidden" name="${name}" value="" />
		</#if>
		</div>
		
		<script>
		magicsoft.select2.initSimpleSelect({
			selector: "#${selectId}", 
			multiple: ${multiple?string("true","false")}, 
			placeholder: "${placeholder}", 
			queryMode: "${queryMode}", 
			entitySymbol: "${entitySymbol}", 
			valueProperty: "${valueProperty}", 
			labelProperty: "${labelProperty}", 
			whereClause: "${whereClause}", 
			orderClause: "${orderClause}", 
			includeEmpty: ${includeEmpty?string("true","false")}, 
			remoteQueryClass: "${remoteQueryClass}", 
			extraQueryParams: {${extraQueryParams}},
			tags: ${tags?string("true","false")},
			quickCreateUrl : "${quickCreateUrl}",
			quickCreateStyle: "${quickCreateStyle}",
			quickCreateTitle: "${quickCreateTitle}",
			clientId : "${model.clientId}",
			enumType: "${enumType}",
			textOnly: "${textOnly?string('true','false')}"
		});
		</script>
	</@widget>
</#macro>

<#-- 树形下拉框 -->
<#-- @param url 树数据加载地址。 -->
<#-- @see <#macro select /> <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#-- @param quickCreateUrl		下拉选择数据源没有时，提供快捷创建url。 -->
<#macro treeselect
	label labelWidth required 
	columnScale style class labelPos quickCreateUrl quickCreateStyle quickCreateTitle
	id name value placeholder propertyPath filterType operator
	entitySymbol valueProperty labelProperty whereClause orderClause url remoteQueryClass extraQueryParams templateSelection prefix suffix 
	readonly=false disabled=readonly multiple=false textOnly=false clientFilter=true tags=false standardPunctuation = "、">
	<@widget widgetType="treeselect" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale style=style class=class propertyPath=propertyPath filterType=filterType operator=operator>
		<#local selectId="_lst_${model.randomHex}_${model.clientId}" />
		<div class="input-group" style="width:100%;">
			${prefix}
			<select class="form-control <#if textOnly && multiple>select-textOnly-multiple</#if> " style="width:100%;" data-url="${url}" id="${selectId}" <#if multiple>multiple="multiple"</#if> <@attributes name=(textOnly && multiple)?string("",name) placeholder=placeholder disabled=disabled />>
				<#if !textOnly>
					<#list getSelectItems(entitySymbol,!multiple,null,null,valueProperty,labelProperty,remoteQueryClass,value,null,"remote") as option>
						<option value="${option.id}" <#if option.id!=''>selected</#if>>${option.text}</option>
					</#list>
				<#elseif  textOnly && !multiple>
					<option value="${value}" selected>${value}</option>
					<option value=""></option>
				<#elseif  textOnly && multiple && value??>
					<#if value?is_sequence>
							<#list value as v><option value="${v}" selected>${v}</option></#list>
					<#else>
						<#list value?split(standardPunctuation) as v>
							<option value="${v}" <#if v?? && v!=''>selected</#if>>${v}</option>
						</#list>
						<#list options as option>
							<#if !(value?split(standardPunctuation)?seq_contains(option.text))><option value="${option.text}" >${option.text}</option></#if>
						</#list>
					</#if>
				</#if>
			</select>
			${suffix}
				<#if quickCreateUrl?? && quickCreateUrl!="">
				<span  class='input-group-addon quick-create' style='cursor: pointer;'><i class="fa fa-pencil-square-o" aria-hidden="true"></i></span>
			</#if>
		</div>
		<div class="readonly-hidden">
		<#if readonly>
			<#if value?is_sequence>
				<#list value as v><input type="hidden" name="${name}" value="${v}" /></#list>
			<#else>	
				<input type="hidden" name="${name}" value="${value}" />
			</#if>
		</#if>
		</div>

		<div class="multiple-hidden">
		<#if textOnly && multiple  >
				<input type="hidden" name="${name}" value="${value}" />
		<#elseif multiple>
			<input type="hidden" name="${name}" value="" />
		</#if>
		</div>
	
		<script>
			<#if textOnly && multiple  >
				$('#${selectId}').on('change',function(){
					$('#${selectId}').parent().nextAll('.multiple-hidden').find('input').val($('#${selectId}').standardSelectAPI('getSelectedOptions','${standardPunctuation}'));
				})
			</#if>
			magicsoft.select2.initTreeSelect({
				selector: '#${selectId}', 
				url: '${url}', 
				quickCreateUrl: '${quickCreateUrl}',
				quickCreateStyle: "${quickCreateStyle}",
				quickCreateTitle: "${quickCreateTitle}",
				multiple: ${multiple?string('true','false')}, 
				placeholder: '${placeholder}', 
				entitySymbol: "${entitySymbol}", 
				valueProperty: "${valueProperty}", 
				labelProperty: "${labelProperty}", 
				whereClause: "${whereClause}", 
				orderClause: "${orderClause}",
				templateSelection: "${templateSelection}",
				clientFilter: ${clientFilter?string('true','false')},
				clientId: "${model.clientId}",
				tags: ${tags?string("true","false")},
				textOnly: "${textOnly?string('true','false')}"
				});
			</script>
	</@widget>
</#macro>

<#-- 多选框（checkbox）。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro checkbox 
	label labelWidth required 
	columnScale style class labelPos
	id name value placeholder propertyPath filterType operator readonly disabled=false>
	<@widget widgetType="checkbox" id=id labelWidth=labelWidth required=required columnScale=columnScale labelPos=labelPos style=style class=class propertyPath=propertyPath filterType=filterType operator=operator>
		<div class="checkbox">
			<label>
				<input type="checkbox" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly /> value="true" <#if value=="true">checked</#if> /> ${label}
			</label>
			<#if !disabled>
				<#-- 下面为了解决checkbox不勾选无法将false返回给后台的问题，按照这种做法，如果checkbox勾选了，则会返回一个true和一个false，不管怎样，我们只取第一个值就行了。 -->
				<#if name??><input type="hidden" name="${name}" value="false" /></#if>
			</#if>
		</div>
	</@widget>
</#macro>

<#-- 多选组（checkboxgroup）。 -->
<#-- @param options 多选组的数据源。类型为freemarker能够识别的集合类型。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro checkboxgroup 
	label labelWidth required 
	columnScale style class labelPos
	id value placeholder propertyPath filterType operator disabled readonly
	entitySymbol remoteQueryClass labelProperty valueProperty whereClause orderClause options name="chkg_${model.randomHex}_${model.clientId}" includeEmpty=false addrValue={}>
	<@widget widgetType="checkboxgroup" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale style=style class=class propertyPath=propertyPath filterType=filterType operator=operator>
		<#if options??>
			<#list options as option>
			<label class="checkbox-inline"><input type="checkbox" ${value!?seq_contains(option.id)?string("checked","")} value="${option.id}" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly /> /> <span>${option.text}</span></label>
			<#if option.addrFlag>
				<#assign optionAddrValue=addrValue["${option.id}"] />
				<input type="text" name="${option.id}" value="${optionAddrValue}"/>
			</#if>
			</#list>
		<#else>
			<#list getSelectItems(entitySymbol,includeEmpty,whereClause,orderClause,valueProperty,labelProperty,remoteQueryClass,"##IGNORE##",null) as option>
			<label class="checkbox-inline"><input type="checkbox" ${value!?seq_contains(option.id)?string("checked","")} value="${option.id}" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly /> /> <span>${option.text}</span></label>
			<#if option.addrFlag>
				<#assign optionAddrValue=addrValue["${option.id}"] />
				<input type="text" name="${option.id}" value="${optionAddrValue}"/>
			</#if>
			</#list>
		</#if>
		<#-- 下面为了解决checkbox不勾选无法将false返回给后台的问题，按照这种做法，如果checkbox勾选了，则会返回一个true和一个false，不管怎样，我们只取第一个值就行了。 -->
		<#if name??><input type="hidden" name="${name}" value="" /></#if>
	</@widget>
</#macro>

<#-- 多选组（checkboxset）。 -->
<#-- @param options 多选组的数据源。类型为freemarker能够识别的集合类型。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#-- options为数据信息,subOptionKey为判断是否有下级-->
<#macro checkboxset label labelWidth required 
	value placeholder disabled readonly propertyPath filterType operator style class labelPos
	options subOptionKey showCheckHelper=true columnScale=1 id="ckbset_${name}_${model.clientId}" name="chkset_${model.randomHex}_${model.clientId}">
	
	<@widget widgetType="checkboxset" columnScale=columnScale style=style class=class labelPos=labelPos propertyPath=propertyPath filterType=filterType operator=operator showLabel=false>
	<fieldset id="${id}" class="magic-checkboxset">
		<legend><label>${label}</label>&nbsp;<#if showCheckHelper>（<a class="fieldset-link">${model.getBundleString('base','words.checkall')}</a>&nbsp;<a class="fieldset-link">${model.getBundleString('base','words.eliminate')}</a>）</#if></legend>
		<#list options as option>
			<#if subOptionKey??&&option[subOptionKey]??>
				<div class="row">
					<div class="col-md-24">
						<fieldset>
							<legend>${option.text}&nbsp;（<a class="fieldset-link">${model.getBundleString('base','words.checkall')}</a>&nbsp;<a class="fieldset-link">${model.getBundleString('base','words.eliminate')}</a>）</legend>
			</#if>
			
			<#if subOptionKey??>
				<#list option[subOptionKey] as subOption>
					<#-- 此处代码与下方略有冗余 begin -->
					<#if subOption_index%6==0>
						<#if subOption_index!=0>
						</div>
						</#if>
						<div class="row">
					</#if>
					<div class="col-md-4">
						<label class="checkbox-inline">
							<input name="${name}" type="checkbox" 
									<#if subOption.checked??&&subOption.checked==1> checked<#elseif value!?seq_contains(option.id)> checked</#if>
									<#if subOption.disabled??&&subOption.disabled==1> disabled</#if> 
									value="${subOption.id}"/> 
							${subOption.text}
						</label>
					</div>
					<#if !subOption_has_next>
						</div>
					</#if>
					<#-- 此处代码与下方略有冗余 end -->
				</#list>
			<#else>
				<#-- 此处代码与下方略有冗余 begin -->
				<#if option_index%6==0>
					<#if option_index!=0>
					</div>
					</#if>
					<div class="row">
				</#if>
				<div class="col-md-4">
					<label class="checkbox-inline">
						<input name="${name}" type="checkbox" 
						<#if subOption.checked??&&subOption.checked==1> checked<#elseif value!?seq_contains(option.id)>checked</#if> 
						<#if option.disabled??&&option.disabled==1> disabled</#if> value="${option.id}"/> 
						${option.text}
					</label>
				</div>
				<#if !option_has_next>
					</div>
				</#if>
			</#if>
			
			<#if subOptionKey??&&option[subOptionKey]??>
						</fieldset>
					</div>
				</div>
			</#if>
		</#list>
	</fieldset>
	</@widget>
	<script>
		$('#${id}').on('click', 'a', function(e) {
			var me = $(this);
			switch (me.text()) {
			case "${model.getBundleString('base','words.checkall')}":
				$(this).parent().parent().find(':checkbox').prop('checked', true);
				break;
			case "${model.getBundleString('base','words.eliminate')}":
				$(this).parent().parent().find(':checkbox:not(:disabled)').prop('checked', false);
				break;
			}
		});
	</script>
	
	<#-- disabled checked -->
</#macro>

<#-- 单选组（radiogroup）。 -->
<#-- @param options 单选组的数据源。类型为freemarker能够识别的集合类型。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro radiogroup 
	label labelWidth required 
	columnScale style class labelPos
	id value placeholder propertyPath filterType operator disabled readonly
	entitySymbol labelProperty valueProperty whereClause orderClause options name="rdog_${model.randomHex}_${model.clientId}" includeEmpty=false>
	<@widget widgetType="radiogroup" id=id label=label labelWidth=labelWidth labelPos=labelPos required=required columnScale=columnScale style=style class=class propertyPath=propertyPath filterType=filterType operator=operator>
		<#if options??>
			<#list options as option>
				<label class="radio-inline"><input type="radio" ${(value=option.id)?string("checked","")} value="${option.id}" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly /> /> ${option.text}</label>
			</#list>
		<#else>
			<#list getSelectItems(entitySymbol,includeEmpty,whereClause,orderClause,valueProperty,labelProperty,remoteQueryClass,"##IGNORE##",null) as option>
				<label class="radio-inline"><input type="radio" ${(value=option.id)?string("checked","")} value="${option.id}" <@attributes name=name placeholder=placeholder disabled=disabled readonly=readonly /> /> ${option.text}</label>
			</#list>
		</#if>
	</@widget>
</#macro>

<#-- 日期字段。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#-- @param linkFormat 		前后台实际传递值的日期格式。 -->
<#-- @param format 		    显示用的日期格式。 -->
<#macro datepicker 
	label labelWidth required  
	columnScale style class labelPos
	id name value placeholder propertyPath filterType operator disabled readonly prefix suffix linkFormat="yyyy-MM-dd" format="${model.defaultDateFormat}" mode='day'>
	<@widget widgetType="datepicker" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale style=style class=class propertyPath=propertyPath filterType=filterType operator=operator>
		<#-- 这里先简单支持日期类型，后续如有日期时间或单独时间格式，再处理。 -->
		<#if value??>
			<#local linkValue=value?string(linkFormat) />
			<#local value=value?string(format) />
		</#if>
		<#if mode="minute">
			<#local startView=0 />
		<#elseif mode='day'>
			<#local startView=2 />
		<#elseif mode='month'>
			<#local startView=3 />
		<#elseif mode='year'>
			<#local startView=4 />
		</#if>
		
		<#local datepickerId="_dp_${model.randomHex}_${model.clientId}" />
		<div class="input-group" style="width:100%;">
			${prefix}
			<input type="text" id="${datepickerId}" class="form-control" <@attributes value=value placeholder=placeholder disabled=disabled readonly=readonly /> />
			<input type="hidden" id="${datepickerId}_lf" name="${name}" value="${linkValue}" />
			${suffix}
		</div>
		<script>
		$('#${datepickerId}').datetimepicker({
			minView: ${startView},
			autoclose: true,
			linkField: '${datepickerId}_lf',
			linkFormat: '${linkFormat?lower_case}',
			language: 'zh-CN',
			startView: ${startView},
			todayBtn: true,
			format: '${format?lower_case}'
		});
		</script>
	</@widget>
</#macro>

<#-- 显示字段。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro display 
	label labelWidth 
	columnScale labelPos
	id name value format style class>
	<@widget widgetType="display" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale style=style class=class>
		<#if format="date"&&value!="">
			<#local value=value?date />
		<#elseif format="datetime"&&value!="">
			<#local value=value?datetime />
		<#elseif value!=""&&format!="">
			<#local value=value?date?string(format) />
		</#if>
		<span class="displayfield"><pre>${value}</pre></span>
	</@widget>
</#macro>

<#-- 日期范围字段。 -->
<#-- @param format 可选项：date、datetime -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro daterange 
	label labelWidth required 
	columnScale  class labelPos
	id name1 name2 value1 value2 placeholder propertyPath operator disabled readonly format="${model.defaultDateFormat}" mode='day' filterType="RANGE" >
	<@widget widgetType="daterange" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale propertyPath=propertyPath filterType=filterType operator=operator class=class>
		<#if value1??>
			<#local linkValue1=value1?string('yyyy-MM-dd') />
			<#local value1=value1?string(format) />
		</#if>
		<#if value2??>
			<#local linkValue2=value2?string('yyyy-MM-dd') />
			<#local value2=value2?string(format) />
		</#if>
		<#if mode='minute'>
			<#local startView=0 />
		<#elseif mode='hour'>
			<#local startView=1 />
		<#elseif mode='day'>
			<#local startView=2 />
		<#elseif mode='month'>
			<#local startView=3 />
		<#elseif mode='year'>
			<#local startView=4 />
		</#if>
		<#local datepickerId="_dpr_${model.randomHex}_${model.clientId}" />
		<div id="${datepickerId}" class="input-group input-append date form_datetime">
			<input type="text"  class="form-control" <@attributes value=value1 placeholder=placeholder disabled=disabled readonly=readonly /> />
			<span class="input-group-addon">${model.getBundleString('base','words.to')}</span>
			<input type="text"  class="form-control" <@attributes value=value2 placeholder=placeholder disabled=disabled readonly=readonly /> />
		</div>
		<div>
			<input type="hidden" id="${datepickerId}_dr0" name="${name1}" value="${linkValue1}" />
			<input type="hidden" id="${datepickerId}_dr1" name="${name2}" value="${linkValue2}" />
		</div>
		<script>
		$('#${datepickerId} input').each(function(i){
			$(this).datetimepicker({
				minView: ${startView},
				startView:${startView},
				autoclose: true,
				linkField: '${datepickerId}_dr'+i,
				linkFormat: 'yyyy-mm-dd',
				language: 'zh-CN',
				todayBtn: true,
				format: '${format?lower_case}'
			})
		})
		
		</script>
	</@widget>
</#macro>

<#-- 数字范围字段。 -->
<#-- @see <#macro labelable /> <#macro widget /> <#macro attributes /> -->
<#macro numberrange 
	label labelWidth required 
	columnScale labelPos
	id name value1 value2 placeholder propertyPath operator disabled readonly prefix suffix class filterType="RANGE">
	<@widget widgetType="numberrange" id=id label=label class=class labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale propertyPath=propertyPath filterType=filterType operator=operator>
		<div class="input-group" style="width:100%;">
			${prefix}
				<input type="text" class="form-control" <@attributes name=name value=value1 placeholder=placeholder disabled=disabled readonly=readonly /> />
				<span class="input-group-addon">${model.getBundleString('base','words.to')}</span>
				<input type="text" class="form-control" <@attributes name=name value=value2 placeholder=placeholder disabled=disabled readonly=readonly /> />
			${suffix}
		</div>
	</@widget>
</#macro>

<#-- 树 -->
<#-- @param id 树渲染div的id。 -->
<#-- @param url 树数据加载地址。 -->
<#-- @param extraQueryParams 后台加载数据时额外的参数。 -->
<#-- @param rootNode 根节点配置，JSON格式。 -->
<#-- @param filter 是否支持过滤，设置为tree将在树上方显示一个搜索框。 -->
<#-- @param settings 为tree增加一些新的参数设置 -->
<#macro tree url extraQueryParams rootNode id="_tree_${model.randomHex}_${model.clientId}" settings="{}" filter=false>
	<div class="magic-tree">
		<#if filter>
		<div class="form-group has-feedback">
			<input type="text" class="form-control">
			<i class="fa fa-search form-control-feedback" aria-hidden="true"></i>
		</div>
		</#if>
		<ul id="${id}" class="ztree"></ul>
		<script>magicsoft.zTree.initTree('#${id}', '${url}', <#if extraQueryParams??>{${extraQueryParams}}<#else>null</#if>, <#if rootNode??>${rootNode}<#else>null</#if>, ${filter?string('true','false')}, <#if settings == ''>""<#else>${settings}</#if>);</script>
	</div>
</#macro>

<#-- 查询面板 -->
<#-- @param id 树渲染div的id。 -->
<#macro searchpanel id showMore=false>
<div id="${id}" class="search-panel">
	<form class="form-horizontal">
		<fieldset class="frequently-used search-fieldset">
			<legend><i class="fa fa-caret-right" aria-hidden="true" style="visibility:hidden"></i>${model.getBundleString('base','words.searchitem')} <#if showMore><a class="btn-search-more" href="#">更多</a></#if> </legend>
			<#nested>
		</fieldset>
	</form>
</div>
</#macro>

<#------------------------------------------------------------------------------------------------------------------
	文件字段。
-------------------------------------------------------------------------------------------------------------------->
<#macro file 
	label labelWidth required 
	columnScale labelPos
	id name disabled readonly
	fileName filePath>
	<@widget widgetType="file" id=id label=label labelWidth=labelWidth required=required labelPos=labelPos columnScale=columnScale>
		<div class="filefield" data-file-name="${fileName}" data-file-path="${filePath}">
			<#if !readonly>
				<a class="linkbutton browse">${model.getBundleString('base','words.browse')}<input type="file" class="file-input" name="${name}" /></a>
				<#if fileName!=null && filePath!=null>
					<a class="linkbutton delete">${model.getBundleString('base','words.delete')}</a>
				</#if>
			</#if>
			<#if fileName!=null && filePath!=null>
				<a class="linkbutton download">${model.getBundleString('base','words.download')}</a>
			</#if>
			<a class="linkbutton cancel" style="display:none;">${model.getBundleString('base','words.cancel')}</a>
			<span>${fileName}</span>
		</div>
		<script>magicsoft.standardFileField.parseFileField();</script>
	</@widget>
</#macro>



<#------------------------------------------------------------------------------------------------------------------
	edittable。
	
	showToolbar : 是否显示按钮
	
	customButtons ： 自定义按钮
	//是否使用控件自带的事件，如果不使用，请给对象的btn添加对应的事件
	customAddHandler
	customRemoveHandler
	customMoveUpHandler
	customMoveDownHandler
	//是否显示添加移除或者上移下移按钮
	showModifyButtons
	showOrderButtons
	
-------------------------------------------------------------------------------------------------------------------->
<#macro edittable 
	label labelWidth required 
	columnScale labelPos  style class height
	name value disabled readonly submitIdOnly dataGridOptions
	defaultValues customButtons extensionPoint1 url customAddHandler=true customRemoveHandler=true customMoveUpHandler=true customMoveDownHandler=true
	id="et" + name + "_" + model.clientId showOrderButtons=false showModifyButtons=true noWrap=true showToolbar=showOrderButtons||showModifyButtons||customButtons??>
	<@widget widgetType="edittable" id=id labelWidth=0 columnScale=columnScale labelPos=labelPos class=class style=style>
		<div class="datagrid-toolbar clearfix" style="border-bottom:0px;">
			<div class="pull-left">
				<@labelable label=label required=required labelWidth=labelWidth />
			</div>
			<#if extensionPoint1??>
				${extensionPoint1}
			</#if>
			<#if showToolbar>
			<div class="pull-right">
				<#if customButtons??>
					${customButtons}
				</#if>
				<#if showOrderButtons>
					<a href="#" class="plain linkbutton btnMoveUp"><i class="fa fa-arrow-up" aria-hidden="true"></i> ${model.getBundleString('base','words.up')}</a>
					<a href="#" class="plain linkbutton btnMoveDown"><i class="fa fa-arrow-down" aria-hidden="true"></i> ${model.getBundleString('base','words.down')}</a>
				</#if>
				<#if showModifyButtons>
					<a href="#" class="plain linkbutton btnAdd"><i class="fa fa-plus-square" aria-hidden="true"></i> ${model.getBundleString('base','words.add')}</a>
					<a href="#" class="plain linkbutton btnRemove"><i class="fa fa-minus-square" aria-hidden="true"></i> ${model.getBundleString('base','words.remove')}</a>
				</#if>
			</div>
			</#if>
		</div>
		
		<table class="easyui-datagrid magic-edittable-content" data-submit-id-only="${submitIdOnly}" data-name="${name}" data-options="<#if url??> url:'${model.viewPath}/records',onLoadError:magicsoft.requestErrorHandler,method:'POST'
			<#else>data:${getJsonString(value)!'[]'}</#if>,pagination:false,<#if height??>height:${height},</#if>remoteSort:false,nowrap:${noWrap},<#if showOrderButtons>
											dragSelection:true,
											onLoadSuccess:function(){
								                $(this).datagrid('enableDnd');
								            }</#if>${dataGridOptions}">  
		     <#nested>
		</table>
		<script>
			magicsoft.standardEditTable.initialize({
				editTableId:'${id}',
				customAddHandler:${customAddHandler},
				customRemoveHandler:${customRemoveHandler},
				customMoveUpHandler:${customMoveUpHandler},
				customMoveDownHandler:${customMoveDownHandler}<#if defaultValues??>,defaultValue:${defaultValues}</#if>
			});
		</script>
	</@widget>
</#macro>

<#macro linkbutton menu text style id="btn_${randomHex}_${model.clientId}">
	<a href="#" id="${id}" class="linkbutton" <#if style??>${style}</#if> >${text}</a>
	<ul class="dropdown-menu" role="menu">
		<#nested>
	</ul>
	<script>
		if($('#${id}').next().find('li').length > 0) {
			magicsoft.findParentDialog('#${id}').on('click', function() {
				$('#${id}').next().hide();
			});
			
			$('#${id}').on('click', function(e) {
				$('#${id}').next().css({
					left: $(this)[0]['offsetLeft'],
					top: $(this)[0]['offsetTop'] + 30
				}).show();
				return false;
			});
			$('#${id}').next().on('click', function(e) {
				$(this).hide();
				return false;
			});
		}
	</script>
</#macro>

<#macro linkbuttonmenu id text iconCls>
	<li role="presentation"><a role="menuitem" id="${id}" tabindex="-1" href="#"><#if iconCls??><img src="${iconCls}"/> &nbsp;</#if>${text}</a></li>
</#macro>


<#------------------------------------------------------------------------------------------------------------------
	headerMenuItem。
	阶段项
-------------------------------------------------------------------------------------------------------------------->
<#macro headerMenuItem id href text disabled active>
	<div class="header-menu-item"  >
		<div id="${id}" class="item-icon <#if active>item-icon-active</#if> <#if disabled>item-icon-disabled<#else>item-icon-default</#if>" href="${href}">
			<div class="item-content">
				${text}
			</div>
		</div>
	</div>
</#macro>
<#------------------------------------------------------------------------------------------------------------------
	headerMenuBar。
	阶段条
	click事件 请注册在 .item-icon-default 上。
-------------------------------------------------------------------------------------------------------------------->
<#macro headerMenuBar id panelId defaultContent>
		<div class="header" data-options="region:'north',split:false,collapsible:false,border:false" class="form-horizontal" style="overflow:hidden;padding:5px;height:123px;">
			<div class="header-menu-bar">
				<#nested>
			</div>
		</div>
	<script>
		$(".header-menu-item").on("click",function (){
			if($(this).find(".item-icon-default").length > 0){
				$(".item-icon-active").removeClass("item-icon-active");
				$(this).find(".item-icon-default").addClass("item-icon-active");
			}
		});
		var left = 0;
		$(".header-menu-item").each(function (index){
			if(index == 0){
				$(this).css("left","-2%");
				return ;
			}
			if(index == $(".header-menu-item").size()){
				$(this).css("left","98%");
				return ;
			}
			left = left + 100 / ($(".header-menu-item").length - 1);
			$(this).css("left",left+"%");
		})
	</script>
</#macro>

